import {
  Entity, PrimaryGeneratedColumn, Column, BeforeInsert
} from 'typeorm';
import NodeAuth from 'node-auth0';
import { Exclude, Expose } from 'class-transformer';
import * as jwt from 'jsonwebtoken';

@Entity('user')
export class UserEntity {
  @Exclude()
  private nodeAuth: NodeAuth;

  constructor() {
    this.nodeAuth = new NodeAuth();
  }

  @PrimaryGeneratedColumn({
    comment: '主键id',
    name: 'id',
    type: 'int',
  })
  id: number;

  @Column('varchar', {
    nullable: false,
    primary: true,
    generated: 'uuid',
    length: 50,
    name: 'uuid',
    comment: 'uuid',
  })
  uuid: string;

  @Column('varchar', {
    nullable: false,
    length: 50,
    name: 'username',
    comment: '用户名',
  })
  username: string;

  @Exclude() //排除字段不返回给前端
  @Column('varchar', {
    nullable: false,
    length: 100,
    name: 'password',
    comment: '用户密码',
  })
  password: string;

  @Column('varchar', {
    nullable: true,
    length: 11,
    name: 'mobile',
    comment: '用户手机号码',
  })
  mobile: string | null;

  @Column('varchar', {
    nullable: true,
    length: 50,
    name: 'email',
    comment: '用户邮箱',
  })
  email: string | null;

  @Exclude()
  @Column('tinyint', {
    nullable: true,
    default: () => 1,
    name: 'status',
    comment: '状态',
  })
  status: number | null;

  @Column('varchar', {
    nullable: false,
    length: 50,
    default: 'nlx',
    name: 'platform',
    comment: '平台',
  })
  platform: string;

  @Column('tinyint', {
    nullable: true,
    default: () => 0,
    name: 'isSuper',
    comment: '0==》普通用户   1==》管理员   2==》超级管理员',
  })
  isSuper: number | null;

  @Column('timestamp', {
    nullable: false,
    default: () => 'CURRENT_TIMESTAMP',
    name: 'createdAt',
    comment: '创建时间',
  })
  createdAt: Date;

  @Column('timestamp', {
    nullable: false,
    default: () => 'CURRENT_TIMESTAMP',
    name: 'updatedAt',
    comment: '最后更新时间',
  })
  updatedAt: Date;

  @Expose() //根据现有字段生成一个新的字段
  get is_active(): string {
    return this.status ? '有效' : '无效';
  }

  @BeforeInsert() // 插件数据库前先给密码加密
  makePassword(): void {
    this.password = this.nodeAuth.makePassword(this.password);
  }
  //检查密码是否正确
  checkPassword(password: string, sqlPassword: string): boolean {
    return this.nodeAuth.checkPassword(password, sqlPassword);
  }

  @Expose() //生产token签名
  private get token() {
    const { id, uuid, username, mobile, email, isSuper } = this;
    //生成签名
    return jwt.sign(
      {
        id,
        uuid,
        username,
        mobile,
        email,
        isSuper,
      },
      process.env.SECRET, // 加盐
      {
        expiresIn: '7d', // 过期时间
      }
    );
  }

  public toResponseObject(isShowToken: boolean): any {
    const { nodeAuth, password, token, ...params } = this;
    if (isShowToken) {
      return {
        token,
        ...params,
      };
    } else {
      return {
        ...params,
      };
    }
  }
}
